#light
namespace FSharp.WebTools

open System
open System.CodeDom
open System.Reflection
open System.Web.UI
open Microsoft.FSharp.Core
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Raw

(*-----------------------------------------------------------------------------------------------*)
module Fix : sig
(*-----------------------------------------------------------------------------------------------*)
// Fixes a few issues with F# quotations

  val ( |PropSet|_| ) : Expr -> (PropertyInfo * Expr list) option
  val ( |PropGet|_| ) : Expr -> (PropertyInfo * Expr list) option
  val ( |MethodCall|_| ) : Expr -> (MethodInfo * Expr list) option
  val ( |CtorCall|_| ) : Expr -> (ConstructorInfo * Expr list) option
end  
  
(*-----------------------------------------------------------------------------------------------*)
module Quotations : sig
(*-----------------------------------------------------------------------------------------------*)
// Quotation extensions for F# -> JavaScript convertor

  type ScriptExpr 
  and ExtendedExpr
  
  val ( |StdExpr|_| ) : ExtendedExpr -> Expr option
  val ( |ExtExpr|_| ) : ExtendedExpr -> ScriptExpr option
  
  val MkStdExprOption : Expr option -> ExtendedExpr option 
  val MkStdExpr : Expr -> ExtendedExpr
  val MkExtExpr : ScriptExpr -> ExtendedExpr
  val MkEmbeddedExpr : string -> ExtendedExpr
  
  val MkExtSeqExpr : ExtendedExpr list -> ExtendedExpr
  val MkFieldSet : ExtendedExpr * string * ExtendedExpr -> ExtendedExpr
  val MkValueRef : string -> ExtendedExpr
  val MkExtLambda : ExprVar list * ExtendedExpr -> ExtendedExpr
  val MkUnresolved : unit -> ExtendedExpr

  val ( |ScriptValueRef|_| )    : ExtendedExpr -> string option
  val ( |ScriptEmbedded|_| )    : ExtendedExpr -> string option
  val ( |ScriptFieldSet|_| )    : ExtendedExpr -> (ExtendedExpr * string * ExtendedExpr) option
  val ( |ScriptSeq|_| )         : ExtendedExpr -> ExtendedExpr list option
  val ( |ScriptLambda|_| )      : ExtendedExpr -> (ExprVar list * ExtendedExpr) option
  val ( |ScriptUnresolved|_| )  : ExtendedExpr -> unit option

(*-----------------------------------------------------------------------------------------------*)
// Extensions for working with classes

  /// Member of the class 
  /// For working with this type use active patterns and Mk functions below..
  type ClassMember
  
  [<Flags>]
  type FieldOptions =
    | None = 0
    | Static = 1

  [<Flags>]
  type MemberOptions =
    | None = 0
    | Static = 1
    | Virtual = 2
    | Overridden = 6
    | Abstract = 8

  /// Constructor declaration 
  /// - ExtendedExpression should be lambda ExtendedExpression
  val ( |Constructor|_| ) : ClassMember -> (MemberInfo * ExtendedExpr) option
  val MkConstructor : #MemberInfo * ExtendedExpr -> ClassMember

  /// Method delcaration
  /// - method name, ExtendedExpression (should be lambda) and return type
  ///   (types of parameters are stored in lambda ExtendedExpression)
  val ( |Method|_| ) : ClassMember -> (MemberInfo * MemberOptions * string * ExtendedExpr * Type option) option
  val MkMethod : #MemberInfo * MemberOptions * string * ExtendedExpr * Type option -> ClassMember

  /// Field declaration
  /// - field name, type and init ExtendedExpression
  val ( |Field|_| ) : ClassMember -> (MemberInfo * FieldOptions * string * Type * ExtendedExpr option) option
  val MkField : #MemberInfo * FieldOptions * string * Type * ExtendedExpr option -> ClassMember

  /// Property declaration
  /// - property name, getter and setter (both should be lambda) and type
  val ( |Property|_| ) : ClassMember -> (MemberInfo * MemberOptions * string * ExtendedExpr option * ExtendedExpr option * Type) option
  val MkProperty : #MemberInfo * MemberOptions * string * ExtendedExpr option * ExtendedExpr option * Type -> ClassMember

  /// Structure that contains information about class -
  /// consists of name, name of base class and members
  type ClassInfo with
    member BaseName : string option with get
    member Members : ClassMember list with get
    member Name : string with get
  end

  /// Creates classInfo structure from class name,
  /// base class name and list of members  
  val MkClassInfo : string -> string option -> ClassMember list -> ClassInfo

end